﻿using System;
using System.Globalization;

using YourLastOptionsDialog.Controls;

namespace YourLastOptionsDialog.ViewModels.Options
{
    /// <summary>
    /// A generic option implementation for all floating point options.
    /// </summary>
    /// <typeparam name="T">The type of the option, must be <see cref="float"/>, <see cref="double"/> or <see cref="decimal"/>.</typeparam>
    public class FloatOption<T> : FloatOptionBase
    {
        private string _textValue;

        private FloatValidator _validator;

        /// <summary>
        /// Gets or sets the actual value of the wrapped underlying source.
        /// </summary>
        public T Value
        {
            get
            {
                return (T)GetAccessor();
            }

            set
            {
                SetAccessor(value);
                RaisePropertyChanged("Value");
            }
        }

        /// <summary>
        /// Gets or sets the value of the wrapped underlying source as string for UI binding.
        /// </summary>
        public string TextValue
        {
            get
            {
                if (string.IsNullOrEmpty(_textValue))
                {
                    _textValue = Value.ToString();
                }

                return _textValue;
            }

            set
            {
                if (_textValue != value)
                {
                    _textValue = value;
                    RaisePropertyChanged("TextValue");

                    // check if we should write back
                    if (Validator.Validate(value) == ValidationResult.Success)
                    {
                        Value = (T)Convert.ChangeType(value, typeof(T), CultureInfo.CurrentCulture);
                    }
                }
            }
        }

        /// <summary>
        /// Gets the floating point value validator.
        /// </summary>
        public override FloatValidator Validator
        {
            get
            {
                if (_validator == null)
                {
                    var validator = new FloatValidator(Minimum, Maximum);
                    _validator = validator;
                }

                return _validator;
            }
        }
    }
}